// Fill out your copyright notice in the Description page of Project Settings.


#include "DelegateInvoker.h"

// Sets default values
ADelegateInvoker::ADelegateInvoker()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

void ADelegateInvoker::InvokeDelegate(EDelegateType Type)
{
	const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, TEXT("EDelegateType"), true);

	if (Maker == nullptr)
	{
		Maker = NewObject<UDelegateMaker>();
	}
	UE_LOG(LogTemp, Warning, TEXT("%s"), *EnumPtr->GetNameStringByValue((int64)Type));
	Maker->MakeDelegate(Type).ExecuteIfBound();

	if (Type == EDelegateType::Object)
	{
		{
			FTestDelegate_Ret& Delegate = Maker->MakeDelegate_Ret();
			if (Delegate.IsBound())
			{
				bool bRet = Delegate.Execute();
				UE_LOG(LogTemp, Warning, TEXT("return %u"), bRet);
			}
		}
		{
			FTestDelegate_Bool& Delegate = Maker->MakeDelegate_Bool();
			Delegate.ExecuteIfBound(true);
		}
		{
			FTestDelegate& Delegate = Maker->MakeDelegate_Payload(100);
			Delegate.ExecuteIfBound();
		}
	}
}

void ADelegateInvoker::InvokeDynamicDelegate()
{
	if (Maker == nullptr)
	{
		Maker = NewObject<UDelegateMaker>();
	}
	FTestDynamicDelegate& Delegate = Maker->MakeDynamicDelegate();
	if (Delegate.IsBound())
	{
		bool bRet = Delegate.Execute(true);
		UE_LOG(LogTemp, Warning, TEXT("%s, return=%u"), TEXT(__FUNCTION__), bRet);
	}
}

void ADelegateInvoker::InvokeMultiDelegate()
{
	if (Maker == nullptr)
	{
		Maker = NewObject<UDelegateMaker>();
	}
	{
		FTestMultiDelegate& Delegate = Maker->AddMultiDelegate();
		Delegate.Broadcast(true);
	}
}

void ADelegateInvoker::InvokeMultiDynamicDelegate()
{
	if (Maker == nullptr)
	{
		Maker = NewObject<UDelegateMaker>();
	}
	{
		FTestDynamicMultiDelegate& Delegate = Maker->AddMultiDynamicDelegate();
		Delegate.Broadcast(true);
	}
	TestDynamicMultiDelegate.Broadcast(true);
}

void ADelegateInvoker::InvokeEvent()
{
	if (!IsValid(Maker))
	{
		Maker = NewObject<UDelegateMaker>();
	}
	Maker->InvokeEvent(true);
}

// Called when the game starts or when spawned
void ADelegateInvoker::BeginPlay()
{
	Super::BeginPlay();
}

// Called every frame
void ADelegateInvoker::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

